import { DecoratorNode, type LexicalNode, type NodeKey } from "lexical";
import type { JSX } from "react";
import { VariableChip } from "../variable-chip";

export type SerializedVariableValueNode = {
  type: "variable-value";
  version: 1;
  variable: string;
};

export class VariableValueNode extends DecoratorNode<JSX.Element> {
  __variable: string;

  static getType(): string {
    return "variable-value";
  }

  static clone(node: VariableValueNode): VariableValueNode {
    return new VariableValueNode(node.__variable, node.__key);
  }

  constructor(variable: string, key?: NodeKey) {
    super(key);
    this.__variable = variable;
  }

  createDOM(): HTMLElement {
    const span = document.createElement("span");
    span.className = "variable-chip";
    span.contentEditable = "false";
    return span;
  }

  updateDOM(): false {
    return false;
  }

  decorate(): JSX.Element {
    return <VariableChip variable={this.__variable} nodeKey={this.__key} />;
  }

  exportJSON(): SerializedVariableValueNode {
    return { type: "variable-value", version: 1, variable: this.__variable };
  }

  getVariable(): string {
    const self = this.getLatest();
    return self.__variable;
  }

  getTextContent(): string {
    return `{{#${this.getVariable()}#}}`;
  }

  static importJSON(
    serializedNode: SerializedVariableValueNode,
  ): VariableValueNode {
    return new VariableValueNode(serializedNode.variable);
  }
}

export function $createVariableValueNode(variable: string) {
  return new VariableValueNode(variable);
}

export function $isVariableValueNode(
  node: LexicalNode | null | undefined,
): node is VariableValueNode {
  return node instanceof VariableValueNode;
}
